﻿
using DataDriven;
using DataService.Common;
using DataService.Core.Collections;
using DataService.Core.Common;
using DataService.Core.Log;
using DataService.Core.ServiceDTO;
using DataService.Extensions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading;

namespace DataService.DataAccessLayer
{
    /// <summary>
    /// SQLite插入数据效率最快的方式就是：开启事务  +   insert语句  +  关闭事务(提交)
    /// 利用事务的互斥性，如果在批量的插入操作前显式地开启一次事务，在插入操作结束后，提交事务，那么所有的操作将只执行一次事务，大大地提高IO效率
    /// </summary>
    public class SQLite : RemoteDB
    {
        public override DatabaseType DBType => DatabaseType.SQLite;

        /// <summary>
        /// 分页查询最快方式
        /// 1.先定位行范围 RowId>开始行 and RowId<=结束行； select 字段 from 表 where RowId>开始行 and RowId<=结束行 and 条件
        /// 2.覆盖索引或索引 查询出主键  select Id; select * from Id>(select Id from xxxx where xxxx)
        /// </summary>
        /// <returns>若没有查到开始位置则返回-1，查到开始位置返回大于等于0</returns>

        //public override Int64 FindStratRow<T>(Expression<Func<T, bool>> whereFunc, string tableName, List<string> pkFields, DbConnection cnn, DbTransaction tran)
        //{
        //    ResolveExpress resolve = new SqliteExpression();
        //    var dic = resolve.ResolveExpression<T>(whereFunc);
        //    object paramValue = dic["values"];
        //    string whereSql = dic["sql"].ToString();
        //    string field = pkFields[0];//Id 字段
        //    Int64 totalRowsCount = FindAllRows(tableName, cnn, tran);
        //    int tempBeatch = 10000;
        //    Int64 tempStarttRow = 0;
        //    Int64 endRow = 0;
        //    while (endRow < totalRowsCount)
        //    {
        //        endRow = tempStarttRow + tempBeatch;
        //        if (endRow > totalRowsCount)
        //        {
        //            endRow = totalRowsCount;
        //        }
        //        string sql = $" select RowId from {tableName} where RowId>{tempStarttRow} and RowId<={endRow} and {whereSql} Order By RowId asc limit 1";
        //        long resultStartRow = MapperService.ScalarInternal<long>(cnn, sql, paramValue, tran, null, null);
        //        if (resultStartRow > 0)
        //        {
        //            return resultStartRow;
        //        }
        //        tempStarttRow = endRow;
        //    }

        //    //string sql = $" select {field} from {tableName} where {whereSql} Order By {field} desc limit 1";

        //    LogTool.TraceLog.WriteLine($"查询开始位置", "查询分页");
        //    return -1;
        //}


        //public override int BeatchInsert<T>(IList<T> dataList, string suffix, DbConnection conn, DbTransaction tran)
        //{
        //    if (Monitor.TryEnter(_insertLock))
        //    {
        //      int count=  base.BeatchInsert(dataList, suffix, conn, tran);
        //        Monitor.Exit(_insertLock);
        //        return count;
        //    }
        //    return 0;
        //}

        protected override string SetTotalRowsSql(string tableName, string dataBaseName, string schema)
        {
            string sql = $"select Max(rowId) from {tableName}";
            return sql;
        }
        /// <summary>
        /// 查询最大Id
        /// </summary>
        public override Int64 FindMaxId(string tableName, string pkFieldName, DbConnection cnn, DbTransaction tran)
        {
            string sql = $"select max({pkFieldName}) from {tableName}";
            Int64 totalCount = MapperService.ScalarInternal<Int64>(cnn, sql, null, tran, null, null, ParameterPrefix);
            return totalCount;
        }

        //public override Int32 FindAllRows<T>(Expression<Func<T, bool>> whereFunc, string tableName, List<string> pkFields, DbConnection cnn, DbTransaction tran)
        //{
        //    string pkIdFields = string.Join(",", pkFields);
        //    ResolveExpress resolve = new ResolveExpress();
        //    var dic = resolve.ResolveExpression<T>(whereFunc);


        //    Stopwatch sw = new Stopwatch();
        //    sw.Start();
        //    object paramValue = dic["values"];
        //    string whereSql = dic["sql"].ToString();
        //    string sql = $"select RowId,{pkIdFields} from {tableName} where {whereSql}";

        //    int tempPageIndex = 1;
        //    int tempPageSize = 10000;
        //    int tempToal = 0;
        //    bool isFlag = false;
        //    object tempData = null;
        //    do
        //    {
        //        int startNum = (tempPageIndex - 1) * tempPageSize;
        //        //string querySql = sql + $" AND rowId>{startNum} limit {tempPageSize};";
        //        string querySql = sql + $" limit {startNum}, {tempPageSize};";
        //        LogTool.TraceLog.WriteLine("Sqlite分页：" + querySql, "查询分页");
        //        var queryData = MapperService.QueryInternal<T>(cnn, querySql, paramValue, tran, null, null);
        //        isFlag = queryData.Any();
        //        if (isFlag)
        //        {
        //            tempToal = tempToal + tempPageSize;
        //        }
        //        tempPageIndex++;
        //    }
        //    while (isFlag);
        //    sw.Stop();
        //    Console.WriteLine($"sqlite查询总记录数({tableName})：,{tempToal}耗时：{sw.ElapsedMilliseconds},查询分页");


        //    return tempToal;

        //}


        /// <summary>
        /// 分页查询最快方式
        /// 1.先定位行范围 RowId>开始行 and RowId<=结束行； select 字段 from 表 where RowId>开始行 and RowId<=结束行 and 条件
        /// 2.覆盖索引或索引 查询出主键  select Id; select * from Id>(select Id from xxxx where xxxx)
        /// </summary>
        public override string SqlAppendWhere<T>(string[] asc, string[] desc, int startRowNum, int maxNum, string querySql, List<string> pkFields, Expression<Func<T, bool>> whereFunc, ref object paramValue)
        {
            //将取值结果集控制在10000条数据范围内,若10000内搜索结果满足每页数据，则直接返回，如果补满足则继续循环取
            //参考sql=select Id from 表名 where PersonnelName like '%测试%' and rowId>4415000 and rowId<=4415100 order by rowId,PersonnelName,Id desc limit 10000
            //示例：第一次 select * from 表 where RowId>0 and Row<=10000 and PersonnelName like '%测试%'
            //若此次搜索的结果不满足每页条数则 取下个循环
            //第二次 select * from 表 where RowId>10000 and Row<=20000 and PersonnelName like '%测试%'
            //一直循环到取出每页数据为止
            ResolveExpress resolve = new SqliteExpression();
            var dic = resolve.ResolveExpression<T>(whereFunc, ParameterPrefix);
            paramValue = dic["values"];
            string whereSql = dic["sql"].ToString();
            string orderbySql = GetOrderby<T>(asc, desc, pkFields);
            int endNum = startRowNum + PageTakeNum;
            //string sql = $"{querySql} WHERE RowId>{startNum} and RowId<={endNum} and {whereSql} {orderbySql} limit {startNum},{maxNum};";
            string sql = $"{querySql} WHERE RowId>{startRowNum} and RowId<={endNum} and {whereSql} {orderbySql} limit {maxNum};";
           TraceLog.WriteLine($"查询分页执行语句：{sql}", "查询分页");
            return sql;
        }

        public override string GetOrderby<T>(string[] asc, string[] desc, List<string> defaultOrders)
        {
            string orderStr = string.Empty;
            StringBuilder stringBuilder = new StringBuilder();
            if (asc != null && asc.Length > 0)
            {
                foreach (var item in asc)
                {
                    stringBuilder.Append(item).Append(",");
                }
                stringBuilder.Length--;
                stringBuilder.Append(" asc ");
            }
            if (desc != null && desc.Length > 0)
            {
                foreach (var item in desc)
                {
                    stringBuilder.Append(item).Append(",");
                }
                stringBuilder.Length--;
                stringBuilder.Append(" desc");
            }
            if (stringBuilder.Length > 0)
            {
                return $"order by rowId,{stringBuilder.ToString()}";
            }
            string field = defaultOrders[0];
            return $"order by rowId,{field}";
        }


        public override string GetIsExistsTableSql(string databaseName, string schemaName)
        {
            string sql = "select Count(1) from sqlite_master where type='table' and  Name=@Name";
            return sql;
        }
        public override List<string> FindAllTableNames(DbConnection conn, DbTransaction tran)
        {
            string sql = "select name from sqlite_master where type='table'";
            var list = MapperService.QueryInternal<string>(conn, sql, null, tran, null, null, ParameterPrefix).ToList();
            return list;
        }
        public override bool CreatTable(Tables tables, DbConnection conn, DbTransaction tran)
        {
            //优化时定时任务提前把第二天的表创建完成
            List<ModelColumns> tableShemas = tables.Columns;
            List<ModelIndexs> tableIndexs = tables.Indexs;
            var tableSchemaTexts = CreateTableSql(tableShemas, tableIndexs);
            string str = string.Join("*", tableSchemaTexts);
            TraceLog.WriteLine(str, "脚本", "Sqlite创建表");
            //此处需要优化
            int count = MapperService.ExecuteSchemaSql(conn, tran, tableSchemaTexts, ParameterPrefix);
            if (count > 0)
            {
                List<string> tempTableNames = new List<string>();
                int hashCode = ConnectionString.GetHashCode();
                if (_tablesFields.ContainsKey(hashCode))
                {
                    tempTableNames = _tablesFields[hashCode];
                    if (!tempTableNames.Any(x => x == tableShemas[0].FullTableName))
                    {
                        tempTableNames.Add(tableShemas[0].FullTableName);
                        _tablesFields[hashCode] = tempTableNames;
                        TraceLog.WriteLine($"创建表结构【CreatTable】：{tableShemas[0].FullTableName}，添加到缓存", $"{DBType}创建表");
                    }

                }
                else
                {
                    tempTableNames.Add(tableShemas[0].FullTableName);
                    _tablesFields[hashCode] = tempTableNames;
                }
            }

            return count > 0;
        }
        public override bool CreateDataBaseSchema(string dbFileDir, string databaseName, DbConnection conn)
        {
            string dbPath = $"{dbFileDir}{databaseName}.db";
            if (File.Exists(dbPath))
            {
                throw new Exception(dbPath + "已存在");
            }
            using (FileStream fs = new FileStream(dbPath, FileMode.Create))
            {

            }
            return true;
        }
        ///// <summary>
        ///// 查询执行计划
        ///// EXPLAIN QUERY PLAN  select RowId from TB_PersonnelInformation_20221121 where ((1=1) and PersonnelName like '%测试%') order by Id asc limit 0,1
        ///// </summary>
        //public override string FindExplain(DbConnection conn, DbTransaction tran, string sql)
        //{
        //     sql = "EXPLAIN QUERY PLAN " + sql;
        //    var list = MapperService.QueryInternal<string>(conn, sql, null, tran, null, null).ToList();
        //    return list;

        //}
        #region 创建架构

        private List<ModelColumns> MadeColumns(DataTable columnData, string tableName, string databaseName)
        {
            List<ModelColumns> list = new List<ModelColumns>();
            for (int i = 0; i < columnData.Rows.Count; i++)
            {
                var itemRow = columnData.Rows[i];
                ModelColumns columns = new ModelColumns();
                columns.TableName = tableName;
                int.TryParse(itemRow["cid"].ToString(), out int colOrder);
                columns.ColOrder = colOrder;
                columns.ColName = itemRow["name"].ToString();
                columns.ColName = columns.ColName.Replace(" ", "");
                string tempType = itemRow["type"].ToString();
                int valueLength = 0;
                int scaleLength = 0;
                if (tempType.Contains("("))
                {
                    string itemType = tempType.Substring(0, tempType.IndexOf('('));
                    columns.ColType = itemType.ToUpper();
                    int num = tempType.IndexOf(')') - tempType.IndexOf('(') - 1;
                    string vallengthStr = tempType.Substring(tempType.IndexOf('(') + 1, num);
                    string[] valArray = vallengthStr.Split(",");
                    if (valArray.Length > 1)
                    {
                        int.TryParse(valArray[0], out valueLength);
                        int.TryParse(valArray[1], out scaleLength);
                    }
                    if (valArray.Length == 1)
                    {
                        int.TryParse(valArray[0], out valueLength);
                    }
                }
                else
                {
                    columns.ColType = tempType;
                }
                columns.ColType = columns.ColType.Replace(" ", "");


                columns.ValueLength = valueLength;
                columns.ColLength = columns.ValueLength;

                columns.ScaleLength = scaleLength;

                columns.IsNullable = itemRow["notnull"].ToString() == "1" ? false : true;

                columns.DefaultValue = itemRow["dflt_value"].ToString();

                columns.FieldDes = string.Empty;
                list.Add(columns);
            }
            return list;
        }


        public override Tables FindAllModelTableSchema(List<string> tableNames, DbConnection conn)
        {
            string dataBaseName = conn.DataSource;
            List<ModelColumns> sqliteColumns = new List<ModelColumns>();
            List<ModelIndexs> resuleIndexs = new List<ModelIndexs>();
            for (int i = 0; i < tableNames.Count; i++)
            {
                string sql = $"PRAGMA table_info('{tableNames[i]}')";
                DataTable dataTable = MapperService.QueryDataTable(conn, sql, null, null, null, null, ParameterPrefix);
                // List<ModelColumns> itemColumns = MapperService.QueryInternal<ModelColumns>(conn, sql, null, null, null, null, ParameterPrefix).ToList();
                sqliteColumns.AddRange(MadeColumns(dataTable, tableNames[i], dataBaseName));

                string indexSql = $"PRAGMA index_list('{tableNames[i]}');";
                DataTable indexDataTable = MapperService.QueryDataTable(conn, indexSql, null, null, null, null, ParameterPrefix);

                foreach (DataRow itemIndexRow in indexDataTable.Rows)
                {
                    string indexName = itemIndexRow["name"].ToString();
                    string fieldSql = $"PRAGMA index_info('{indexName}');";
                    DataTable fieldDataTable = MapperService.QueryDataTable(conn, fieldSql, null, null, null, null, ParameterPrefix);
                    foreach (DataRow itemFieldRow in fieldDataTable.Rows)
                    {
                        ModelIndexs itemModelIndexs = new ModelIndexs();
                        itemModelIndexs.TableName = tableNames[i];
                        itemModelIndexs.IndexName = itemIndexRow["name"] == null ? "" : itemIndexRow["name"].ToString();
                        int.TryParse(itemFieldRow["cid"].ToString(), out int tempVal);
                        itemModelIndexs.IndexId = tempVal;
                        itemModelIndexs.ColumnName = itemFieldRow["name"].ToString();
                        //itemModelIndexs.Sort = tempVal;
                        string dType = itemIndexRow["origin"].ToString();
                        itemModelIndexs.PrimaryKey = dType == "pk";
                        string duniqueStr = itemIndexRow["unique"].ToString();
                        int.TryParse(duniqueStr, out int val);
                        itemModelIndexs.UQIQUE = val == 1;
                        resuleIndexs.Add(itemModelIndexs);
                    }
                }
            }
            Tables tables = new Tables()
            {
                Columns = sqliteColumns,
                Indexs = resuleIndexs
            };
            return tables;
        }


        private List<string> CreateTableSql(List<ModelColumns> tableSchemas, List<ModelIndexs> tableIndexs)
        {
            List<string> textSchemas = new List<string>();
            var tableNameList = tableSchemas.Select(x => x.FullTableName).Distinct().ToList();
            foreach (var itemTableName in tableNameList)
            {
                var colSchemaList = tableSchemas.Where(x => x.FullTableName == itemTableName).ToList();
                StringBuilder stringBuilder = new StringBuilder();
                string tableName = itemTableName;//分表后缀,前调用分表前处理
                List<ModelIndexs> itemTableIndexs = tableIndexs.Where(x => x.FullTableName == itemTableName).ToList();
                //这里需要按照规则生成表名
                stringBuilder.Append($"CREATE TABLE {tableName}(");

                foreach (var itemCol in colSchemaList)
                {
                    stringBuilder.Append(itemCol.ColName).Append(" ");
                    stringBuilder.Append(GetColType(itemCol)).Append(" ");
                    stringBuilder.Append(GetColIsNull(itemCol)).Append(" ");
                    stringBuilder.Append(DefaultValue(itemCol)).Append(",");
                }

                //创建 主键
                if (itemTableIndexs != null && itemTableIndexs.Count > 0)
                {
                    StringBuilder indexBuilder = GetPrimaryKey(itemTableIndexs, itemTableName);
                    stringBuilder.Append(indexBuilder);
                }
                stringBuilder.Length--;
                stringBuilder.AppendLine(");");

                //一个表只有一个聚集索引，这里默认主键是聚集索引
                //创建约束、创建索引、组合索引、创建联合主键、创建自增字段、
                //创建索引前需要先删除该索引；DROP INDEX 表名.索引名[,…]
                //如果这个表没有主键，就需要查找是否有聚集索引
                //
                //with (drop_existing = on|off)，加上这个的意思是如果这个索引还在表上就drop 掉然后在create 一个新的。特别是在聚集索引上使用这个就可以不会引起非聚集索引的重建
                //UNIQUE 表示创建的索引具有唯一性
                //CLUSTERED 指明创建的索引为聚集索引
                //NONCLUSTERED 指明创建的索引为非聚集索引
                //ASC、DESC 指定特定的索引列的排序方式为升序(默认)或降序

                //创建普通索引
                if (itemTableIndexs != null && itemTableIndexs.Count > 0)
                {
                    StringBuilder indexBuilder = GetSimpleIndexScheme(itemTableIndexs, itemTableName);
                    stringBuilder.Append(indexBuilder);
                }
                textSchemas.Add(stringBuilder.ToString());

            }

            return textSchemas;
        }

        protected override string GetColType(ModelColumns colDTO)
        {
            string tempColType = colDTO.ColType.ToLower();
            if (tempColType == "char" || tempColType == "nchar")
            {
                int tempLength = colDTO.ValueLength;
                if (tempLength == -1)
                {
                    return $"char(8000)";
                }
                return $"char({tempLength})";
            }
            else if (tempColType == "nvarchar" || tempColType == "varchar")
            {
                int tempLength = colDTO.ValueLength;
                if (tempLength == -1)
                {
                    return $"varchar(8000)";
                }
                return $"varchar({tempLength})";
            }
            else if (tempColType == "binary" || tempColType == "varbinary" || tempColType == "image")
            {
                return $"BLOB";
            }
            else if (tempColType == "tinyint" || tempColType == "smallint" || tempColType == "int" || tempColType == "bigint")
            {
                return tempColType;
            }
            else if (tempColType == "bit")
            {
                return "BOOLEAN";
            }
            else if (tempColType == "uniqueidentifier")
            {
                return "VARCHAR(36)";
            }
            else if (tempColType == "datetime" || tempColType == "date" || tempColType == "time")
            {
                return tempColType;
            }
            else if (tempColType == "smalldatetime")
            {
                return "DATETIME";
            }
            else if (tempColType == "double" || tempColType == "float")
            {
                return "REAL";
            }
            else if (tempColType == "smallmoney" || tempColType == "money")
            {
                return tempColType;
            }
            else if (tempColType == "decimal" || tempColType == "numeric")
            {
                int tempLength = colDTO.ValueLength;
                int num = colDTO.ScaleLength;
                return $"{tempColType}({tempLength},{num})";
            }
            else
            {
                return tempColType;
            }
        }
        private string GetColIsNull(ModelColumns colDTO)
        {
            return colDTO.IsNullable ? "NULL" : "NOT NULL";
        }
        private string DefaultValue(ModelColumns colDTO)
        {
            if (string.IsNullOrEmpty(colDTO.DefaultValue))
            {
                return "";
            }
            return $"default{colDTO.DefaultValue}";
        }
        private StringBuilder GetPrimaryKey(List<ModelIndexs> itemTableIndexs, string itemTableName)
        {
            StringBuilder stringBuilder = new StringBuilder();
            var indexNames = itemTableIndexs.Select(x => x.IndexName).Distinct().ToList();
            int index = 0;
            foreach (string itemIndexName in indexNames)
            {

                var tempIndexs = itemTableIndexs.Where(x => x.IndexName == itemIndexName).ToList();
                string colNames = string.Join(",", tempIndexs.Select(x => x.ColumnName));
                var itemTableIndexsDTO = tempIndexs.FirstOrDefault();
                //  string rand =$"PK_{itemTableName}";
                //这里认为主键是聚集索引，正常逻辑，主键也应该是聚集索引
                if (itemTableIndexsDTO.PrimaryKey)
                {
                    index++;
                    string tempIndexName = $"PK_{itemTableName}_{index}";
                    //在建立聚集索引的时候在多个字段上建立聚集索引是没有任何意义的；因为聚集索引查找是根据建立索引的第一个字段来查找；这里索引索引排序取第一条排序方式

                    // string pkIndexSql = $"ALTER TABLE {itemTableName} ADD CONSTRAINT {tempIndexName} PRIMARY KEY({colNames} {itemTableIndexsDTO.Sort}); ";
                    //CONSTRAINT cs_pk PRIMARY KEY (Id,FieldDes ASC),
                    string pkIndexSql = $"CONSTRAINT {tempIndexName} PRIMARY KEY({colNames})";

                    stringBuilder.Append(pkIndexSql).Append(",");
                }
                //创建表时创建唯一索引
                //if (itemTableIndexsDTO.UQIQUE && !itemTableIndexsDTO.PrimaryKey)
                //{
                //    // CONSTRAINT cs_t1111 UNIQUE(Flag ASC),
                //    string tempSql = $"CONSTRAINT {tempIndexName} UNIQUE({colNames} {itemTableIndexsDTO.Sort})";
                //    stringBuilder.Append(tempSql).Append(",");
                //}
            }
            return stringBuilder;
        }
        private StringBuilder GetSimpleIndexScheme(List<ModelIndexs> itemTableIndexs, string itemTableName)
        {
            //CREATE INDEX 语句中列的排序会影响查询的性能
            StringBuilder stringBuilder = new StringBuilder();
            var indexNames = itemTableIndexs.Select(x => x.IndexName).Distinct().ToList();
            int index = 0;
            foreach (string itemIndexName in indexNames)
            {
                index++;
                var tempIndexs = itemTableIndexs.Where(x => x.IndexName == itemIndexName).ToList();
                string colNames = string.Join(",", tempIndexs.Select(x => x.ColumnName));
                var itemTableIndexsDTO = tempIndexs.FirstOrDefault();

                //string tempIndexName = itemIndexName;
                if (itemTableIndexsDTO.UQIQUE && !itemTableIndexsDTO.PrimaryKey)
                {
                    string tempIndexName = $"UNIQUE_INDEX_{itemTableName}_{index}";
                    string tempSql = $"Create UNIQUE Index {tempIndexName} ON {itemTableName}({colNames});";
                    stringBuilder.Append(tempSql);
                }
                if (!itemTableIndexsDTO.PrimaryKey && !itemTableIndexsDTO.UQIQUE)
                {
                    string tempIndexName = $"INDEX_{itemTableName}_{index}";
                    string tempSql = $"CREATE INDEX {tempIndexName} ON {itemTableName}({colNames});";
                    stringBuilder.Append(tempSql);
                }
            }
            return stringBuilder;
        }
        #endregion


        #region 创建模型文件
        public string ModelTableSql
        {
            get
            {
                string str = string.Format(@"CREATE TABLE {0} (
    Id           BIGINT Not Null PRIMARY KEY,
    TableName    VARCHAR (100),
DataBaseName    VARCHAR (100),
Identity    BOOLEAN,
    ColOrder     INT,
    ColName      VARCHAR (50),
    Flag         BOOLEAN,
    ColType      VARCHAR (30),
    ColLength    INT,
    ValueLength  INT,
    ScaleLength  INT,
    IsNullable   BOOLEAN,
    DefaultValue VARCHAR (100),
    FieldDes     VARCHAR (100),
FullTableName VARCHAR (100)
);", nameof(ModelColumns));
                return str;
            }
        }
        public string ModelIndexSql
        {
            get
            {
                string str = string.Format(@"CREATE TABLE {0} (
    Id         BIGINT  Not Null PRIMARY KEY,
    IndexName  VARCHAR (100),
    DataBaseName VARCHAR (100),
    IndexId    INT,
    IndexType  VARCHAR (100),
    ColumnName VARCHAR (100),
    Sort       VARCHAR (10),
    PrimaryKey BOOLEAN,
    UQIQUE     BOOLEAN,
    Type_Desc  VARCHAR (100),
TableName VARCHAR (100),
FullTableName VARCHAR (100)
);", nameof(ModelIndexs));
                return str;
            }
        }

        public string ModelInitDataSql
        {
            get
            {
                string str = string.Format(@"CREATE TABLE {0} (
    Id         BIGINT  Not Null PRIMARY KEY,
    DataFields  VARCHAR (8000)
);", nameof(ModelInitData));
                return str;
            }
        }


        public override void CreateModelSchema(DbConnection sqliteConn, DbTransaction tran)
        {
            #region 校验表结构
            List<string> tableNames = FindAllTableNames(sqliteConn, tran);
            if (!tableNames.Any(x => x == nameof(ModelColumns)))
            {
                MapperService.ExecuteInternal(sqliteConn, ModelTableSql, null, tran, null, null, ParameterPrefix);
            }
            if (!tableNames.Any(x => x == nameof(ModelIndexs)))
            {
                MapperService.ExecuteInternal(sqliteConn, ModelIndexSql, null, tran, null, null, ParameterPrefix);
            }
            if (!tableNames.Any(x => x == nameof(ModelInitData)))
            {
                MapperService.ExecuteInternal(sqliteConn, ModelInitDataSql, null, tran, null, null, ParameterPrefix);
            }
            #endregion
        }
        public override void CreateModelFile(Tables tables, DbConnection sqliteConn, DbTransaction tran)
        {
            base.Insert<ModelColumns>(tables.Columns, "", sqliteConn, tran);
            base.Insert<ModelIndexs>(tables.Indexs, "", sqliteConn, tran);
            base.Insert<ModelInitData>(tables.ModelInitDatas, "", sqliteConn, tran);
        }


        #endregion



    }
}
